

#include <kernel/kernel.h>
#include <kernel/limits.h>
#include <kernel/error/error.h>
#include "userid.h"

#define USERID_DEFAULTPERMISSIONS 0700

/* A "user" is something that requires resources.  Ex. people and
 * processes are users, while blocks, handles, and userids are
 * resources.  */

struct UserEntry {
	int Permissions;
	userid Group;
	char Lock;
};


struct UserEntry UserTable [MAXUSERS];
static userid NextNewUser = 0;

extern void userid_init ()
{
	userid id;

	for (id = 0; id < MAXUSERS; ++id)
	{
		UserTable [id].Lock = 0;
	}
}


extern userid userid_request ()
{
	userid id;
	char giveup = 0;

	/*TODO:  another place where we could loop forever if
	 * resources become scarce */

	for (id = 0; UserTable [id].Lock; ++id)
	{
		if (id == MAXUSERS - 1)
		{
			if (giveup != 0)
			{
				error_log (ERROR_NOUSERID);

				return BADUSERID;
			}

			id = 0;
			giveup = 1;
		}

	}

	UserTable [id].Lock = 1;
	UserTable [id].Permissions = USERID_DEFAULTPERMISSIONS;
	UserTable [id].Group = id;

	return id;
}


extern void userid_release (userid _id)
{

	/* lastly free the userid */
	UserTable [_id].Lock = 0;
}

/* This obviously makes no attempt to verify that _id
 * was ever "invited" to _group.  I think this is okay,
 * because a user program shouldn't really be calling kernel
 * functions unless it has superuser priviledges. */
extern int userid_join (userid _id, userid _group)
{
	if (UserTable [_group].Lock > 0 || UserTable [_id].Lock > 0)
	{
		/* bad user or group */

		return -1;
	}

	UserTable [_id].Group = _group;

	return 0;
}


